package com.jhl.seckill.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.github.benmanes.caffeine.cache.Cache;
import com.jhl.seckill.entity.User;
import com.jhl.seckill.service.GoodsService;
import com.jhl.seckill.vo.DetailVo;
import com.jhl.seckill.vo.GoodsVo;
import com.jhl.seckill.vo.RespBean;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping("goods")

@Slf4j
public class GoodsController {


    @Autowired
    Cache<String, Object> caffineCache;
    @Autowired
    private GoodsService GoodsService;
    @Autowired
    private RedisTemplate redisTemplate;

    @SentinelResource(value = "/goods/list")
    @RequestMapping(value = "/list", method = RequestMethod.GET)
    @ResponseBody
    public RespBean doGoodsList(HttpServletRequest request, HttpServletResponse response) {
//        log.info("toList的用户="+user.getUsername());
        ValueOperations valueOperations = redisTemplate.opsForValue();


        caffineCache.getIfPresent("goodsList");
//        使用线程安全类进行查询
        Object caffineGoodsList = caffineCache.asMap().get("goodsList");
        if (caffineGoodsList != null) {
            log.info("从caffine查询商品列表");
            return RespBean.success(caffineGoodsList);
        }

//        caffine查找不到从redis查找
        Object goodsList = valueOperations.get("goodsList");
        if (!StringUtils.isEmpty(goodsList)) {
            log.info("从缓存查询商品列表，并放入caffine");
            caffineCache.asMap().put("goodsList", goodsList);
            return RespBean.success(goodsList);
        }

        List<GoodsVo> goodsListFromDB = GoodsService.findGoodsVo();

//        缓存商品列表
        if (!StringUtils.isEmpty(goodsListFromDB)) {
            log.info("从数据库查询商品列表，并放入caffine和redis");
            caffineCache.asMap().put("goodsList", goodsListFromDB);
            valueOperations.set("goodsList", goodsListFromDB, 60, TimeUnit.SECONDS);
        }

        log.info("查询成功，准备返回");
        return RespBean.success(goodsListFromDB);
    }

    /**
     * 商品详情页面
     */
    @RequestMapping(value = "/detail/{goodsId}", method = RequestMethod.GET)
    @ResponseBody
    public RespBean doGoodsDetail(@PathVariable Long goodsId, HttpServletRequest request, HttpServletResponse response) throws Exception {
        ValueOperations valueOperations = redisTemplate.opsForValue();

//        获取token
        String username = request.getHeader("user");


        log.info("当前登录用户为：" + username);
        GoodsVo goodsVo = null;
        goodsVo = (GoodsVo) valueOperations.get("goodsDetail:" + goodsId);
        if (goodsVo == null) {
            goodsVo = GoodsService.findGoodsVobyGoodsId(goodsId);
            valueOperations.set("goodsDetail:" + goodsId, goodsVo, 60, TimeUnit.SECONDS);
        }

//        获取秒杀商品的开始时间
        Date startDate = goodsVo.getStartDate();
        Date endDate = goodsVo.getEndDate();
        Date nowDate = new Date();
        //秒杀状态
        int seckillStatus = 0;
        //秒杀倒计时
        int remainSeconds = 0;

        if (nowDate.before(startDate)) {
            //秒杀还未开始0
            remainSeconds = (int) ((startDate.getTime() - nowDate.getTime()) / 1000);
        } else if (nowDate.after(endDate)) {
            //秒杀已经结束
            seckillStatus = 2;
            remainSeconds = -1;
        } else {
            //秒杀进行中
            seckillStatus = 1;
            remainSeconds = 0;
        }

        DetailVo detailVo = new DetailVo();
        User user1 = new User();
        user1.setUsername(username);
        detailVo.setUser(user1);
        detailVo.setGoodsVo(goodsVo);
        detailVo.setRemainSeconds(remainSeconds);
        detailVo.setSeckillStatus(seckillStatus);

        log.info("goods/detail返回的数据=" + detailVo);
        return RespBean.success(detailVo);
    }

}
